// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// See License.txt in the project root for license information.
using System;
using System.Cloud.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Actors;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
//using System.Windows.Shapes;

namespace ActorFramework.Fakebook
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void ConnectButton_Click(object sender, RoutedEventArgs args)
        {
            ConnectButton.Content = "Connecting...";

            String fabricAddress = FabricAddressTextBox.Text;
            String firstName = FirstNameTextBox.Text;
            String lastName = LastNameTextBox.Text;
            String accountName = FakebookPerson.GetAccountName(firstName, lastName);
            App.AccountName = accountName;
            App.FabricAddress = fabricAddress;
            App.ConnectThroughGateway = ConnectThroughGatewayCheckBox.IsChecked.GetValueOrDefault();

            try
            {
                FakebookPerson client = new FakebookPerson(fabricAddress, accountName, App.ConnectThroughGateway);
                App.FakebookClient = client;

                EnsureActorAssembliesAreUpToDate(client);

                bool exists = client.EnsureAccountExists();
                if (exists)
                {
                    var next = new UserHomePage(accountName);
                    next.Show();
                    this.Hide();
                }
                else
                {
                    client.FirstName = firstName;
                    client.LastName = lastName;

                    await Task.Run(() => client.MakeDependentActors());

                    // Pop up a new user page
                    var newUser = new EditProfile(true);
                    newUser.Show();
                    this.Hide();
                }
            }
            catch (Exception e)
            {
                ConnectButton.Content = "Connect failed.";
                Exception excToDisplay = e;
                Exception aggregate = e as AggregateException;
                if (aggregate != null)
                    excToDisplay = aggregate.InnerException;
                MessageBox.Show(String.Format("Connection failed.  {0}: {1}", excToDisplay.GetType(), excToDisplay.Message), "Failed connecting to Fakebook");
            }
        }

        private void EnsurePersonActorAssemblyIsUpToDate(FakebookPerson fakebookClient, String binariesDir)
        {
            FabricActorClient actorClient = fakebookClient.GetFabricActorClient();
            String personActorPath = Path.Combine(binariesDir, "PersonActor\\bin\\debug\\PersonActor.dll");
            Assembly personActorAssembly = Assembly.LoadFrom(personActorPath);
            actorClient.AddAssembly(personActorAssembly.FullName, File.ReadAllBytes(personActorAssembly.Location));

            String fakebookClientPath = Path.Combine(binariesDir, "FakebookClient\\bin\\debug\\FakebookClient.dll");
            Assembly fakebookClientAssembly = Assembly.LoadFrom(fakebookClientPath);
            actorClient.AddAssembly(fakebookClientAssembly.FullName, File.ReadAllBytes(fakebookClientAssembly.Location));
        }

        private void EnsureActorAssembliesAreUpToDate(FakebookPerson fakebookClient)
        {
            String binariesDir = Path.Combine(Environment.CurrentDirectory, "..\\..\\..");

            EnsurePersonActorAssemblyIsUpToDate(fakebookClient, binariesDir);

            /*  Different actor!
            String newsfeedActorPath = Path.Combine(binariesDir, "NewsfeedActor\\bin\\debug\\NewsfeedActor.dll");
            Assembly newsfeedActorAssembly = Assembly.LoadFrom(newsfeedActorPath);
            fabricClient.AddAssembly(newsfeedActorAssembly.FullName, File.ReadAllBytes(newsfeedActorAssembly.Location));
             */
        }
    }
}
